//
//  UUUserManager.m
//  UUCharterSupplier
//
//  Created by ZhangAo on 09/03/2018.
//  Copyright © 2018 UUCharter. All rights reserved.
//

#import "UUUserManager.h"
#import <UUFoundation/DKDataManager.h>
#import "UUUserUpdateAvatarRequestModel.h"
#import "UUUserInfoRequestModel.h"
#import <UUFoundation/UUPersistenceManager.h>

@interface UUUserManager ()

@property (nonatomic, strong) DKDataManager *userInfoRequest;

@property (nonatomic, strong) UUUserInfo *userInfo;
@property (nonatomic, assign) BOOL userInfoCacheIsInvalid;

@end

@implementation UUUserManager

- (void)asyncFetchUserInfoWithCompleteBlock:(void (^)(UUUserInfo *userInfo, NSError *error))completeBlock {
    if (self.userInfo != nil && !self.userInfoCacheIsInvalid) {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, self.userInfo, nil);
        });
        return;
    }
    
    NSString *key = @"asyncFetchUserInfoWithCompleteBlock";
    
    [self addBlock:completeBlock withKey:key];
    if ([self blocksWithKey:key].count > 1) {
        return;
    }
    
    UUUserInfoRequestModel *requestModel = [UUUserInfoRequestModel new];
    WEAK_SELF();
    [self.userInfoRequest requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            UUUserInfo *userInfo = (UUUserInfo *)responseModel;
            weakSelf.userInfo = userInfo;
            weakSelf.userInfoCacheIsInvalid = NO;
            [weakSelf saveUserInfo:userInfo];
            
            [weakSelf notifyObserversWithSelector:@selector(userDidUpdate) withObject:nil];
        }
        
        [[weakSelf blocksWithKey:key] enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            void (^block)(UUUserInfo *userInfo, NSError *error) = obj;
            BLOCK_SAFE_CALLS_In_Main_Queue(block, weakSelf.userInfo, error);
        }];
        [weakSelf clearBlocksForKey:key];
    }];
}

- (UUUserInfo *)fetchUserInfo {
    if (self.userInfo == nil) {
        self.userInfo = [self loadUserInfo];
    }
    
    return self.userInfo;
}

- (void)setNeedsUpdateUserInfo {
    self.userInfoCacheIsInvalid = YES;
}

- (void)asyncUpdateUserAvatar:(NSString *)avatar completeBlock:(void (^)(NSError *))completeBlock {
    DKAssert(avatar != nil);
    
    UUUserUpdateAvatarRequestModel *requestModel = [UUUserUpdateAvatarRequestModel new];
    requestModel.avatar = avatar;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            self.userInfo.avatar = avatar;
            [weakSelf notifyObserversWithSelector:@selector(userDidUpdate) withObject:nil];
        }
        
        BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, error);
    }];
}

#pragma mark - Private methods

- (DKDataManager *)userInfoRequest {
    if (_userInfoRequest == nil) {
        _userInfoRequest = [DKDataManager new];
    }
    
    return _userInfoRequest;
}

- (void)saveUserInfo:(UUUserInfo *)userInfo {
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:userInfo];
    [GetPersistenceManager().commonDefaults setObject:data forKey:@"UserInfo"];
}

- (UUUserInfo *)loadUserInfo {
    NSData *data = [GetPersistenceManager().commonDefaults objectForKey:@"UserInfo"];
    if (data) {
        return [NSKeyedUnarchiver unarchiveObjectWithData:data];
    } else {
        return nil;
    }
}

@end
